<template>
    <div>
        <el-button @click="onExplain">
            {{ btnContext }}
        </el-button>
        <span class="tip">摄像头拍摄内容仅用于识别二维码</span>
        <el-dialog
            v-model="onCameraExplain"
            :before-close="handleClose"
            width="600px"
            title="请将二维码对准摄像头"
        >
            <div
                v-loading="videoLoading"
                class="preview-video"
            >
                <video-scanner
                    v-if="onCameraExplain"
                    :src="videoStream"
                    @onplay="handleScanner"
                >
                </video-scanner>
            </div>
        </el-dialog>
    </div>
</template>

<script lang="ts">
import {
  Options, Vue, Ref, Emit,
} from 'vue-property-decorator';
import { ElDialog, ElButton } from 'element-plus';

import QrcodeDecoder from '@/common/qrcode-decoder';

import VideoScanner from './video-scanner.vue';

@Options({
  components: {
    ElDialog,
    ElButton,
    VideoScanner,
  },
})
export default class CameraExplain extends Vue {
    onCameraExplain = false;

    qrcodeData = '';

    videoStream: MediaStream | null = null;

    videoLoading = false;

    get showResult() {
      return !!this.qrcodeData;
    }

    get showScanner() {
      return this.onCameraExplain && !this.showResult;
    }

    get btnContext() {
      return this.onCameraExplain ? '摄像头启用中' : '点击启用摄像头';
    }

    @Ref('video')
    video!: HTMLVideoElement;

    @Emit('decodeSuccess')
    decodeSuccess(data: string) {
      this.handleClose();
      this.qrcodeData = data;
      return data;
    }

    async onExplain() {
      this.onCameraExplain = true;
      this.videoLoading = true;
      this.videoStream = await navigator.mediaDevices.getUserMedia({
        video: true,
        audio: false,
      });
    }

    async handleScanner(video: HTMLVideoElement) {
      this.videoLoading = false;
      const decoder = new QrcodeDecoder();
      const qrcode = await decoder.decodeByVideo(video);
      if (qrcode) {
        this.decodeSuccess(qrcode.data);
      }
    }

    handleClose() {
      this.onCameraExplain = false;
      const track = this.videoStream?.getTracks()[0];
        track?.stop();
        this.videoStream = null;
    }

    handleResultClose() {
      this.qrcodeData = '';
    }
}
</script>

<style lang='less' scoped>
    .tip{
        padding-left: 10px;
        vertical-align: bottom;
        font-size: 10px;
        color: #878787;
    }
</style>
